package com.next

import grails.transaction.Transactional
import org.springframework.security.access.annotation.Secured

import static org.springframework.http.HttpStatus.*

@Secured(['ROLE_ADMINISTRATOR', 'ROLE_COMPANY_ADMINISTRATOR', 'ROLE_COMPANY_USER'])
@Transactional(readOnly = true)
class AccountController
{
    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def springSecurityService
    def exportService
    // @CompileStatic
    def index(Integer max)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def accountList = Account.findAll("from Account where user.username = '${username}' order by modifiedDate desc", [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Account.executeQuery("select count(id) from Account where user.username = '${username}'")

        respond accountList, model: [accountCount: count[0], params: params]
    }

    // @CompileStatic
    def show(Account account)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def addressList = Address.findAll("from Address where account.id = ?", [account.id])
        def noteList = Note.findAll("from Note where account.id = ?", [account.id])
        def attachmentList = Attachment.findAll("from Attachment where account.id = ?", [account.id])
        def appointmentList = Activity.findAll("from Activity where account.id = ? and type.id = ?", [account.id, ActivityType.find("from ActivityType where name = 'Appointment'")?.id])
        def taskList = Activity.findAll("from Activity where account.id = ? and type.id = ?", [account.id, ActivityType.find("from ActivityType where name = 'Task'")?.id])
        def teamList = AccountTeam.findAll("from AccountTeam where account.id = ?", [account.id])
        def flexFieldInstanceList = FlexFieldInstance.findAll("from FlexFieldInstance where account.id = ?", [account.id])
        def opportunityList = Opportunity.findAll("from Opportunity where account.id = ? order by modifiedDate desc", [account.id])

        // 模块权限控制
        def accountTeam = AccountTeam.find("from AccountTeam where account.id = ? and user.username = ?", [account.id, username])
        def teamRole = accountTeam?.teamRole
        def contactPermission = accountTeam?.contactPermission
        def activityPermission = accountTeam?.activityPermission
        def teamPermission = accountTeam?.teamPermission
        def attachmentPermission = accountTeam?.attachmentPermission
        def notePermission = accountTeam?.notePermission
        def flexFieldPermission = accountTeam?.flexFieldPermission
        def addressPermission = accountTeam?.addressPermission

        respond account, model: [addressList: addressList, noteList: noteList, attachmentList: attachmentList, appointmentList: appointmentList, taskList: taskList, teamList: teamList, flexFieldInstanceList: flexFieldInstanceList, teamName: 'accountTeam', teamRole: teamRole, contactPermission: contactPermission, activityPermission: activityPermission, teamPermission: teamPermission, attachmentPermission: attachmentPermission, notePermission: notePermission, flexFieldPermission: flexFieldPermission, addressPermission: addressPermission, opportunityList: opportunityList]
    }

    // @CompileStatic
    def create()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        Company company = Company.findAll()[0]
        Boolean enableTerritory = company.enableAccountTerritory
        respond new Account(params), model: [enableTerritory: enableTerritory, user: user]
    }

    @Transactional
    def save(Account account)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (account == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (account.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond account.errors, model: [user: user], view: 'create'
            return
        }

        Company company = Company.findAll()[0]
        Boolean enableTerritory = company.enableAccountTerritory
        if (enableTerritory && !account?.territory)
        {
            flash.message = "请选择销售区域"
            respond account, view: 'create', model: [enableTerritory: enableTerritory, user: user]
        }
        else
        {
            account.save flush: true

            request.withFormat {
                form multipartForm {
                    flash.message = message(code: 'default.created.message', args: [message(code: 'account.label',
                                                                                            default: 'Account'), account
                        .id])
                    redirect account
                }
                '*' { respond account, [status: CREATED] }
            }
        }
    }

    // @CompileStatic
    def edit(Account account)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond account, model: [user: user]
    }

    @Transactional
    def update(Account account)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (account == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (account.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond account.errors, model: [user: user], view: 'edit'
            return
        }

        account.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'account.label',
                                                                                        default: 'Account'), account
                    .id])
                redirect account
            }
            '*' { respond account, [status: OK] }
        }
    }

    @Transactional
    def delete(Account account)
    {

        if (account == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        account.delete flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'account.label',
                                                                                        default: 'Account'), account
                    .id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NO_CONTENT }
        }
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'account.label',
                                                                                          default: 'Account'), params
                    .id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    // @CompileStatic
    def searchAccount()
    {
        def username = springSecurityService?.getPrincipal()?.username
        String name = params["name"]
        String type = params["type"]
        String level = params["level"]

        String sql = "from Account where user.username = '${username}'"
        if (name)
        {
            sql += " and name like '%${name}%'"
        }
        if (type)
        {
            sql += " and type.name like '%${type}%'"
        }
        if (level)
        {
            sql += " and level.name like '%${level}%'"
        }
        String countSql = "select count(id) " + sql
        sql += " order by modifiedDate desc"

        def list = Account.findAll(sql, [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Account.executeQuery(countSql)

        respond list, model: [accountCount: count[0], params: params], view: 'index'
    }

    def exportAccount()
    {
        if (!params.max)
        {
            params.max = 10
        }
        def username = springSecurityService?.getPrincipal()?.username
        String name = params["name"]
        String type = params["type"]
        String level = params["level"]
        String sql = "from Account where  user.username = '${username}'"
        if (name)
        {
            sql += " and name like '%${name}%'"
        }
        if (type)
        {
            sql += " and type.name like '%${type}%'"
        }
        if (level)
        {
            sql += " and level.name like '%${level}%'"
        }
        String countSql = "select count(id) " + sql
        sql += " order by modifiedDate desc"
        def list = Account.findAll(sql)
        def count = Account.executeQuery(countSql)
        if (params?.f && params.f != "html")
        {
            response.contentType = grailsApplication.config.grails.mime.types[params.f]
            response.setHeader("Content-disposition", "attachment; filename=account.${params.extension}")
            List fields = ["name", "alias", "type.name", "level.name", "industry.name", "numberOfEmployees", "website", "registeredCapital", "parent.name", "territory.name", "user.fullName", "description", "active", "createdDate", "modifiedDate"]
            Map labels = ["name": "客户名称", "alias": "曾用名", "type.name": "类型", "level.name": "分级", "industry.name": "行业", "numberOfEmployees": "雇员数量", "website": "网站", "registeredCapital": "注册资本", "parent.name": "上级客户", "territory.name": "销售区域", "user.fullName": "所有者", "description": "描述", "active": "启用", "createdDate": "创建时间", "modifiedDate": "修改时间"]
            exportService.export(params.f, response.outputStream, list, fields, labels, [:], [:])
        }
    }
}
